using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.IdentityModel.Tokens;

namespace Crux.Core.Jwt;
/// <summary>
/// 
/// </summary>
public class JwtTokenGenerator(JwtOption ticket)
{
    private List<Claim> claims = new List<Claim>();
    private readonly JwtSecurityTokenHandler _handler = new JwtSecurityTokenHandler();
    /// <summary>
    /// 
    /// </summary>
    /// <param name="ticket"></param>
    /// <returns></returns>
    public static JwtTokenGenerator CreateGenerator(JwtOption ticket) => new JwtTokenGenerator(ticket);
    /// <summary>
    /// 创建token
    /// </summary>
    /// <param name="claims"></param>
    /// <returns></returns>
    public string CreateToken(params Claim[] claims)
    {
        var securityKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(ticket.Key));

        var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);

        var expires = DateTime.UtcNow.Add(ticket.Expires);

        var token = new JwtSecurityToken(
                    claims: claims,
                    notBefore: DateTime.UtcNow,
                    issuer: ticket.Issuer,
                    audience: ticket.Audience,
                    expires: expires,
                    signingCredentials: credentials);

        return _handler.WriteToken(token);
    }
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public string CreateToken() => CreateToken(claims.ToArray());
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public JwtTokenGenerator AddClaim(Claim claim)
    {
        if (claim is null)
            return this;

        claims.Add(claim);
        return this;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public JwtTokenGenerator AddClaim(
        string key,
        string value)
    {
        if (string.IsNullOrEmpty(key) ||
            string.IsNullOrEmpty(value))
            return this;

        claims.Add(new Claim(key, value));
        return this;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public JwtTokenGenerator AddClaim(
        string key,
        object value,
        string issuer)
    {
        if (string.IsNullOrEmpty(key) ||
             value is null ||
            string.IsNullOrEmpty(issuer))
            return this;

        claims.Add(new Claim(key, $"{value}", issuer));
        return this;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public JwtTokenGenerator AddClaim(
        string key,
        object value,
        string valueType,
        string issuer)
    {
        if (string.IsNullOrEmpty(key) ||
             value is null ||
            string.IsNullOrEmpty(issuer))
            return this;

        claims.Add(new Claim(key, $"{value}", valueType, issuer));
        return this;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public JwtTokenGenerator AddClaim(
        string key,
        object value
    )
    {
        if (string.IsNullOrEmpty(key) ||
            value is null) return this;

        claims.Add(new Claim(key, $"{value}"));
        return this;
    }
}
